<?php
class RM_Module_Insurances extends RM_Module implements RM_Extras_Interface, RM_Unit_Copy_Interface
{
    /**
     * @param RM_Unit_Row $original
     * @param RM_Unit_Row $copy
     * @return void
     */
    function copyInformation(RM_Unit_Row $original, RM_Unit_Row $copy)
    {
        $unitInsurancesModel = new RM_UnitInsurances();
        $unitInsurances = $unitInsurancesModel->getByUnit($original);
        foreach ($unitInsurances as $unitInsurance) {
            $unitInsurancesModel->insert(array(
                'unit_id' => $copy->getId(),
                'insurance_id' => $unitInsurance->insurance_id
            ));
        }
    }

    /**
     * Recalculate all for reservation, after some of the unit details has been changed
     *
     * @abstract
     * @param RM_Reservation_Row $reservation
     * @return bool
     */
    function recalculate(RM_Reservation_Row $reservation)
    {
        $summaryModel = new RM_ReservationSummary();
        $model = new RM_Insurances();
        $details = $reservation->getDetails();
        foreach ($details as $detail) {
            $summaryRows = $summaryModel->fetchByReservationDetail($detail);
            foreach ($summaryRows as $summaryRow) {
                if ($summaryRow->type == self::SUMMARY_TYPE) {
                    $row = $model->find($summaryRow->row_id)->current();
                    if ($row == null) {
                        continue;
                    }
                    $summaryRow->total_amount = -$row->calculate($detail->transform()) * $summaryRow->value;
                    $summaryRow->save();
                }
            }
        }
    }

    /**
     * Returns HTML for a summary reservation page to present current system
     *
     * @abstract
     * @param RM_Reservation_Details $detail
     * @return string HTML code to paste
     */
    public function getSummary(RM_Reservation_Details $detail)
    {
        $model = new RM_Insurances();
        $rows = $model->getByUnit($detail->getUnit());
        if (0 == $rows->count()) {
            return "";
        }

        $request = RM_Environment::getConnector()->getRequestHTTP();
        $request->setControllerName('Insurances');
        $request->setActionName('summary');
        $controller = new RM_User_InsurancesController(
            $request,
            new Zend_Controller_Response_Http()
        );
        $controller->setFrontController(Zend_Controller_Front::getInstance());
        $controller->view->unit = $detail->getUnit();

        $config = new RM_Config();
        $controller->view->currencySymbol = $config->getValue('rm_config_currency_symbol');

        $translate = RM_Environment::getInstance()->getTranslation();
        $rowTypes = array(
            'day' =>  $translate->_('User.Insurances.Type', 'Day'),
            'percentage' => $translate->_('User.Insurances.Type', 'Percentage'),
            'single' => $translate->_('User.Insurances.Type', 'Single')
        );

        $viewRows = array();
        $compulsoryRows = array();
        foreach ($rows as $row) {
            $viewRow = array(
                'id' => $row->id,
                'name' => $row->getName(),
                'type' => $rowTypes[$row->type],
                'value' => RM_Environment::getInstance()->roundPrice(
                    $row->calculateBy(
                        $detail->getTotal(),
                        $detail->getPeriod()->getSeconds()
                    )
                ),
                'compulsory' => $row->compulsory,
                'max' => $row->max,
                'min' => $row->min
            );
            $viewRows[] = $viewRow;
            if ($row->compulsory) {
                $compulsoryRows[] = $viewRow;
            }
        }
        $controller->view->rows = $viewRows;
        $controller->view->compulsoryRows = $compulsoryRows;

        return $controller->view->render('Insurances/summary.phtml');
    }

    /**
     * This string is for rm_reservation_summary table
     */
    const SUMMARY_TYPE = 'insurances';

    public function  __construct()
    {
        $this->name = 'Insurances';
    }

    public function deleteLanguage($locale)
    {
        parent::deleteLanguage($locale);
        $model = new RM_Insurances;
        $model->deleteLanguage($locale);
    }

    public function addLanguage($locale)
    {
        parent::addLanguage($locale);
        $model = new RM_Insurances;
        $model->addLanguage($locale);
    }

    /**
     * This method will return node object for main admin menu tree.
     * Every child classes could overload this method to return any of the node object.
     * If there is no need to present a module in the main admin tree overloaded method should return NULL
     *
     * @return stdClass | null
     */
    public function getNode()
    {
        $std = new stdClass;

        $std->id = $this->name.'_EditJson_NoAjax';
        $std->text = $this->getName();

        $std->iconCls = 'RM_modules_leaf_icon';
        $std->leaf = 'true';
        return $std;
    }

    public function install()
    {
        parent::install();

        //Add iso columns into rm_insurances table for each already installed language
        $languageModule = new RM_Languages();
        $languages = $languageModule->fetchAll();

        require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Insurances.php');
        $insurancesModel = new RM_Insurances();
        foreach ($languages as $language){
            $insurancesModel->addLanguage($language->iso);
        }
    }

    public function getConfigNode()
    {
        return null;
    }

    /**
     * Validate selection for the user GUI
     *
     * @param array $data in format [system name][unit id][row id] = user selected value
     * @return bool
     */
    public function applySelection(Zend_Controller_Request_Abstract $request, RM_Reservation_Details $detail)
    {
        $data = $request->getParam('rm_insurances', array());
        if (is_array($data) == false) {
            return false;
        }
        if (count($data) == 0) {
            return $detail;
        }

        if (isset($data[$detail->getUnit()->id]) == false) {
            return $detail;
        }

        if (is_array($data[$detail->getUnit()->id]) == false) {
            return false;
        }

        if (count($data[$detail->getUnit()->id]) == 0) {
            return $detail;
        }

        $model = new RM_Insurances();
        $rowIDs = $data[$detail->getUnit()->id];

        $rowObjects = array();
        foreach ($rowIDs as $rowID => $value) {
            $row = $model->find($rowID)->current();
            if ($row == null) {
                continue;
            }
            if ($row->isBelongTo($detail->getUnit()) == false){
                continue;
            }
            if (($value > $row->max || $value < $row->min) && $value != 0){
                continue;
            }
            $rowObject = new RM_Insurances_Object(
                $row,
                $value * $row->calculateBy($detail->getTotal(), $detail->getPeriod()->getSeconds()),
                $value
            );
            $rowObjects[] = $rowObject;
        }

        $detail->addExtras($rowObjects);
        return $detail;
    }

    /**
     * Get insurances objects from detail.
     *
     * @param RM_Reservation_Details $detail
     * @return array with RM_Extras_Object_Interface
     */
    protected function _getInsuranceObjects(RM_Reservation_Details $detail)
    {
        $rowObjects = $detail->getExtras();

        $insuranceIDs = array();
        $insuranceObjects = array();
        foreach ($rowObjects as $object){
            if ($object instanceof RM_Insurances_Object) {
                $insuranceObjects[] = $object;
                $insuranceIDs[] = $object->getID();
            }
        }

        $model = new RM_Insurances();
        $compulsoryInsurances = $model->getByUnit($detail->getUnit(), true);
        foreach ($compulsoryInsurances as $compulsoryInsurance) {
            if (false == in_array($compulsoryInsurance->id, $insuranceIDs)) {
                $insuranceObjects[] = new RM_Insurances_Object(
                    $compulsoryInsurance,
                    $compulsoryInsurance->calculateBy($detail->getTotal(), $detail->getPeriod()->getSeconds()),
                    $compulsoryInsurance->min
                );
            }
        }

        return $insuranceObjects;
    }

    /**
     * Assign insurances to reservation
     *
     * @param RM_Reservation_Details $detail
     * @param RM_Reservation_Details_Row $detailRow
     * @return void
     */
    public function assign(RM_Reservation_Details $detail, RM_Reservation_Details_Row $detailRow)
    {
        $rowObjects = $this->_getInsuranceObjects($detail);
        foreach ($rowObjects as $object) {
            $summaryModel = new RM_ReservationSummary();
            $summaryModel->insert(array(
                'row_id' => $object->getID(),
                'type' => self::SUMMARY_TYPE,
                'reservation_detail_id' => $detailRow->id,
                'value' => $object->getValue(),
                'total_amount' => $object->getPrice(),
                'name' => $object->getName()
            ));
        }
    }
}